﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Data.GameData;
using Data.GameData.Utils;
using Data.GameData.GameMap;
using Common.TokenReader;
using GUIDialogs;

namespace GameFramework
{
    public static class Framework
    {
        /// <summary>
        /// Load each file in the specified path, build it and then store it in the data store
        /// </summary>
        /// <param name="basePath">The path to the data files</param>
        public static void LoadGameDataFiles(string basePath)
        {
            // Pre-load each file from the base directory
            string[] filesToLoad = Directory.GetFiles(basePath);

            foreach (string fileName in filesToLoad)
            {
                int start = fileName.LastIndexOf('\\');
                int end = fileName.IndexOf(".");

                string file = fileName.Substring(start+1, end-start-1);
                
                TokenReader reader = new TokenReader(basePath, file);
                reader.Load();

                GameObject obj = null;
                foreach (MetaObject meta in reader.GetMetaObjectList)
                {
                    obj = GameDataFactory.BuildGameObject(meta.Name);
                    obj.BuildFromMetaData(meta);

                    GameDataStore.Add(meta.Name, obj);
                }
            }
        }

        /// <summary>
        /// Generate the basic starting information and data for a new race
        /// </summary>
        /// <param name="race">The race to generate</param>
        public static void CreateRaceStartingSystem(Race race)
        {
            // Basic stats
            race.EconomicLevel = 2;

            if (race.HomeSystem == null)
            {
                // Create a StarSystem
                StarSystem homeSys = new StarSystem();
                homeSys.Type = StarSystemType.SINGLE;
                homeSys.Enviroment = StarSystemEnviroment.NORMAL;

                StarSystemInformation homeInfo = new StarSystemInformation(homeSys.Id, race.Id, homeSys.MapId, "Home");
                homeInfo.OwnerId = race.Id;
                homeInfo.IsHomeSystem = true;

                // Create the Sun
                SystemBody sun = new SystemBody(homeSys.Id, SystemBodyType.SUN, SystemBodyEnviroment.TYPE_O3, 3, 0, null);
                sun.StarType = StarType.YELLOW_STAR;
                sun.MapPosition = new MapIndex(homeSys.MapId, 35, 35);
                homeSys.AddSun(sun);
 


                StarSystemDetails ssDetails = new StarSystemDetails(homeSys, race);
                ssDetails.HideGenerateButton = true;
                ssDetails.ShowDialog();



                homeInfo.Name = ssDetails.StarSystemName;

                //  Add to the race
                StarSystem.Add(homeSys);
                race.AddOwnedStarSystem(homeInfo);
                race.HomeSystem = homeInfo;
                //race.AddPopulation(homePop);

                // Add an empty shipyard
                Unit unit = new Unit(new ShipClass(), UnitType.Starbase);
                unit.ShipYard = new Shipyard();
                unit.MapPosition = race.Populations.OrderByDescending(pop => pop.Size).First().SettledBody.MapPosition;
                unit.ImageName = @"Generic Counters\SpaceSta.gif";
                race.AddStarbase(unit);

                // Initial details
                double gpv = 0.0;
                foreach (Population pop in race.Populations)
                    gpv += pop.MonthlyIncome();

                race.MonthlyMcTotal = gpv - race.MaintenanceCosts;
            }
        }

        public static void ProcessPreGameTurn()
        {
            foreach (Race race in Race.Races)
            {
                if (race.InitialTurn)
                {
                    race.MonthlyMcTotal = 0.0;
                    race.InitialTurn = false;
                }

                // Economic Phase
                //  Population Growth
                //  Calculate GPV
                double gpv = Math.Round(race.MonthlyMcTotal * 1.02, 1);
                foreach (Population pop in race.Populations)
                {
                    pop.Size += pop.MonthlyGrowth();
                    gpv += Math.Round(pop.MonthlyIncome(), 1);
                }

                //  Make req'ed payments
                //  Maintainance
                race.MonthlyMcTotal = Math.Round(gpv - race.MaintenanceCosts, 1);
                race.TurnComplete = false;
            }

            Game.ActiveGame.TurnNumber += 1;
        }

        public static void ProcessPostGameTurn()
        {
            // Economic Phase
            //  Spend
            //  Record changes in economy
            //  Make/Pay for political offers

            // Information Phase

            // Activities Phase

            // Political Phase

            // Record Keeping Phase
        }
    }
}
